package com.anlogic.sdk.utils.toolchain;

import com.anlogic.sdk.utils.EnvUtils;
import com.anlogic.sdk.utils.options.ChipType;
import com.anlogic.sdk.utils.options.CpuType;

public class ToolchainUtils {
	// arm toolchain definition
	public static final String GNU_ARM_GCC = "GNU Arm Embedded GCC";
	public static final String GME_ARM_GCC = "GNU MCU Eclipse ARM Embedded GCC";
	public static final String LINARO_AARCH64_GCC = "Linaro AArch64 Linux GNU";
	
	// riscv toolchain definition
	public static final String RISCV_NUCLEI_GCC = "RISC-V Nuclei GCC";
	public static final String RISCV_ANLOGIC_GCC = "RISC-V Anlogic GCC";
	public static final String GME_RISCV_GCC = "GNU MCU RISC-V GCC";
	public static final String RISC_V_GCC_NEWLIB = "RISC-V GCC/Newlib";
	
	// toolchain properties
	public static final String BUILD_TOOLS_PATH_KEY = "buildTools.path";
	public static final String TOOLCHAIN_PATH_KEY = "toolchain.path.%d";
	
	public static String getId(String toolchainName) {
		long fUniqueId = Integer.toUnsignedLong(toolchainName.hashCode());
		return Long.toString(fUniqueId);
	}
	
	public static boolean IsLegalToolchain(String toolchainId) {
		if (getId(GNU_ARM_GCC).equals(toolchainId) || getId(GME_ARM_GCC).equals(toolchainId) || getId(LINARO_AARCH64_GCC).equals(toolchainId)) {
			return true;
		}
		if (getId(RISCV_NUCLEI_GCC).equals(toolchainId) || getId(RISCV_ANLOGIC_GCC).equals(toolchainId) || getId(GME_RISCV_GCC).equals(toolchainId) || getId(RISC_V_GCC_NEWLIB).equals(toolchainId)) {
			return true;
		}
		return false;
	}
	
	public static boolean isAArch64Toolchain(String toolchainId) {
		if (getId(GNU_ARM_GCC).equals(toolchainId) || getId(LINARO_AARCH64_GCC).equals(toolchainId)) {
			return true;
		}
		return false;
	}
	
	public static boolean isAArch32Toolchain(String toolchainId) {
		if (getId(GME_ARM_GCC).equals(toolchainId)) {
			return true;
		}
		return false;
	}
	
	public static boolean isRiscvToolchain(String toolchainId) {
		if (getId(RISCV_NUCLEI_GCC).equals(toolchainId) || getId(RISCV_ANLOGIC_GCC).equals(toolchainId) || getId(GME_RISCV_GCC).equals(toolchainId) || getId(RISC_V_GCC_NEWLIB).equals(toolchainId)) {
			return true;
		}
		return false;
	}
	
	public static String getToolchainKey(String os, String arch, String projectType) {
		int hash = Math.abs(getToolchainName(os, arch, projectType).hashCode());
		String key = String.format(TOOLCHAIN_PATH_KEY, hash);
		return key;
	}
	
	public static String getBuildToolsPath() {
		return ToolchainProperty.getString("BUILD_TOOL_PATH");
	}
	
	public static String getToolchainName(String os, String arch, String projectType) {
		String osType = os.toUpperCase().contains("LINUX") ? "LINUX" : "BM";
		return ToolchainProperty.getString(String.format("%s_%s_%s_TOOLCHAIN_NAME", osType, arch.toUpperCase(), projectType.toUpperCase()));
	}
	
	public static String getToolchainPrefix(String os, String arch, String projectType) {
		String osType = os.toUpperCase().contains("LINUX") ? "LINUX" : "BM";
		return ToolchainProperty.getString(String.format("%s_%s_%s_TOOLCHAIN_PREFIX", osType, arch.toUpperCase(), projectType.toUpperCase()));
	}
	
	public static String getToolchainPath(String os, String arch, String projectType) {
		String osType = os.toUpperCase().contains("LINUX") ? "LINUX" : "BM";
		return ToolchainProperty.getString(String.format("%s_%s_%s_TOOLCHAIN_PATH", osType, arch.toUpperCase(), projectType.toUpperCase()));
	}
	
	public static String getOpenocdPath() {
		return ToolchainProperty.getString("OPENOCD_PATH");
	}
	
	public static String getOpenocdCfgPath(String arch, String projectType) {
		return ToolchainProperty.getString(String.format("%s_%s_OPENOCD_CFG_PATH", arch.toUpperCase(), projectType.toUpperCase()));
	}
	
	public static String getGdbClientCommands(String arch, String projectType) {
		return ToolchainProperty.getString(String.format("%s_%s_GDB_CLIENT_COMMANDS", arch.toUpperCase(), projectType.toUpperCase()));
	}
	
	public static String getGdbServerOther(String arch, String projectType) {
		return ToolchainProperty.getString(String.format("%s_%s_GDB_SERVER_OTHER", arch.toUpperCase(), projectType.toUpperCase()));
	}
	
	public static String getGDBExecutable(String os, String arch, String projectType) {
		String gdbExecutable = getToolchainPath(os, arch, projectType) + "/" + getToolchainPrefix(os, arch, projectType) + "gdb";
		if (EnvUtils.isWindows()) {
			gdbExecutable = gdbExecutable + ".exe";
		}
		return gdbExecutable;
	}
	
	public static String getOpenOCDExecutable() {
		String openOCDExecutable = getOpenocdPath() + "/openocd";
		if (EnvUtils.isWindows()) {
			openOCDExecutable = openOCDExecutable + ".exe";
		}
		return openOCDExecutable;
	}
	
	public static String getGdbServerOtherOptions(String arch, String projectType) {
		return String.format("%s -f \"%s\"", getGdbServerOther(arch, projectType), getOpenocdCfgPath(arch, projectType));
	}
	
	public static boolean getRunPlatInit(String chipName) {
		if (ChipType.isDr1(chipName) || ChipType.isSOC66080(chipName)) {
			return true;
		}
		return false;
	}
	
	public static String getGdbServerPort(String chipName, String procName) {
		String ret = "3333";
		if (ChipType.isDr1m90(chipName) && procName.equals(CpuType.A35_1.getName())) {
			ret = "3334";
		}
		return ret;
	}
	
	public static String getGdbCliPort(String chipName, String procName) {
		String ret = "7777";
		if (chipName.equals(ChipType.DR1M90.getName()) && procName.equals(CpuType.A35_1.getName())) {
			ret = "7778";
		}
		return ret;
	}
}
